package GUIs;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import MVC.DataObserver;
import THREADS.CustomerThreads;
import THREADS.ParcelThread;
import THREADS.WorkThread;
import LOG.*;

public class SimulatorGUI extends JFrame implements ActionListener{
	
	private JMenuItem export_menu;
	private JMenuItem exit_menu;
	private JMenuItem insert_customer;
	private JMenuItem insert_parcel;
	private JMenuItem stop_menu;;
	private JButton startButton;
	private CustomerPanel customer_panel;
	private WorkerPanel worker_panel;
	private ParcelPanel parcel_panel;
	private UpdatePanel update_panel;
	private DataObserver data_observer;
	private Thread [] worker_thread = new Thread[3];
	
	/**
	 * Constructor to create an object  of Simulator Form with data_observer and initial a set of variable
	 * @param data_observer the object of Observer pattern 
	 */
	public SimulatorGUI(DataObserver data_observer){		
		this.data_observer = data_observer;
		
		this.setTitle("Depot Simulator System");
		this.setSize(700, 500);
		this.setLocation(200, 20);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setJMenuBar(getMainmenu());

		data_observer.readFromFile("CustomerList.txt");
		Logger.writeLog("Adding Customer list into System.");
		
		data_observer.readFromFile("ParcelList.txt");
		Logger.writeLog("Adding Parcel list into System.");

		customer_panel = new CustomerPanel(data_observer);
		parcel_panel = new ParcelPanel(data_observer);

		this.setLayout(new BorderLayout(5,5));
		
		JPanel display_panel = new JPanel();
		display_panel.setLayout(new GridLayout(1,2,20,0));
		display_panel.add(customer_panel);
		display_panel.add(parcel_panel);
		this.add(display_panel,BorderLayout.CENTER);
		
		JPanel depot_panel = new JPanel();
		depot_panel.setLayout(new BorderLayout(5,5));
		worker_panel = new WorkerPanel(data_observer);
		update_panel = new UpdatePanel();
		depot_panel.add(worker_panel,BorderLayout.CENTER);
		depot_panel.add(update_panel,BorderLayout.EAST);	
		this.add(depot_panel,BorderLayout.SOUTH);
		startButton = worker_panel.getStartButton();
		startButton.addActionListener(this);
		
		worker_thread[0] = new Thread(new WorkThread(1,data_observer));
		worker_thread[1] = new Thread(new WorkThread(2,data_observer));
		worker_thread[2] = new Thread(new WorkThread(3,data_observer));
		
		
		this.setVisible(true);
	}
	
	/**
	 * Method to get new speed or gap time of Threads
	 * @return the gap-time of Threads
	 */
	public int getTime(){
		return update_panel.getTime();
	}	
	/**
	 * Method to get new MenuBar
	 * @return new JMenuBar
	 */
	public JMenuBar getMainmenu(){
		JMenuBar main_menu = new JMenuBar();		
		JMenu file_menu = new JMenu("File "); 			
		export_menu = new JMenuItem("Export");
		export_menu.addActionListener(this);
		file_menu.add(export_menu);	
		stop_menu = new JMenuItem("Stop");
		stop_menu.addActionListener(this);
		file_menu.add(stop_menu);		
		exit_menu = new JMenuItem("Exit");
		exit_menu.addActionListener(this);
		file_menu.add(exit_menu);		
		
		JMenu funtion_menu = new JMenu("Functions");
		
		insert_customer = new JMenuItem("Insert New Customer");
		funtion_menu.add(insert_customer);		
		insert_customer.addActionListener(this);
		
		insert_parcel = new JMenuItem("Insert New Parcel");
		funtion_menu.add(insert_parcel);
		insert_parcel.addActionListener(this);	
		
		main_menu.add(file_menu);
		main_menu.add(funtion_menu);
		
		return main_menu;
	}
	/**
	 * Method to add Actions to buttons
	 * @param action_a action for "Start" button
	 * @param action_b action for "Insert" button
	 * @param action_c action for "Update" button
	 * @param action_d action for "break" button
	 */
	public void addsetListener(ActionListener action){
		update_panel.getAlterButton().addActionListener(action);
	}
	
	/**
	 * Method to perform the actions for different buttons
	 */
	@Override
	public void actionPerformed(ActionEvent arg0) {
		if(arg0.getSource() == this.export_menu){
			data_observer.writeToFile("FinalReport.txt");
			Logger.writeLog("User exports the final report");
		}
		else if(arg0.getSource() == this.stop_menu){
			data_observer.set_Run(false);
			worker_panel.getStartButton().setEnabled(false);
			Logger.writeLog("User stops all worker threads ");
		}
		else if(arg0.getSource() == this.exit_menu){
			 int option = JOptionPane.showConfirmDialog(null, "Do you want to exit?", "Exit",JOptionPane.YES_OPTION);
			 if(option == JOptionPane.YES_NO_OPTION){
				 Logger.writeLog("User closes the software");
				 for(int i=0; i<3; i++){			
						worker_thread[i].interrupt();
					}
				 System.exit(0);
			 }
		}
		else if(arg0.getSource() == this.startButton){			
			Logger.writeLog("Processes the collections in System");
			for(int i=0; i<3; i++){			
				worker_thread[i].start();
				
				try {
					Thread.sleep(1);
				} catch (InterruptedException e1) {e1.printStackTrace();}
			}
		}
		else if(arg0.getSource() == this.insert_customer){
			Logger.writeLog("Adds new customer into System");
			CustomerThreads new_customer = new CustomerThreads(data_observer);
			new_customer.start();
		}
		else if(arg0.getSource() == this.insert_parcel){
			Logger.writeLog("Adds new Parcels into Parcel List.");
			new ParcelThread(data_observer).start();
		}
	}
}